﻿#include "cpu.h"
#include "sigar.h"
#include "sigar_format.h"
#include "string.h"

#include <windows.h>
#include <iostream>
using namespace std;

cpu::cpu()
{

}

int cpu::cpu_test()
{
    //获取cpc信息
    demo_cpu_info_list infoList;
    getCpuInfo(infoList);

    //获取cpu当前状态
    dome_cpu_stat_list cpu_stat_list;
    getCpuStat(cpu_stat_list);

    //获取cpu使用率等
    dome_cpu_perc_list cpu_perc_list;
    getCpuPerc(cpu_perc_list);

    return 0;
}

void cpu::getCpuInfo(demo_cpu_info_list &infoList)
{
    //结构体置空
    memset(&infoList, 0, sizeof(demo_cpu_info_list));

    sigar_t *sigar;
    sigar_open(&sigar);

    // 获取cpu列表
    sigar_cpu_info_list_t cpu_infos;
    sigar_cpu_info_list_get(sigar, &cpu_infos);

    infoList.number = cpu_infos.number;
    infoList.size = cpu_infos.size;

    //为每个存储cup信息的结构体申请内存
    infoList.data = new demo_cpu_info[infoList.number];

    for (unsigned long i=0; i < cpu_infos.number; i++)
    {
        sigar_cpu_info_t cpu = cpu_infos.data[i];

        memset(&infoList.data[i], 0, sizeof(demo_cpu_info));
        //给demo_cpu_info的参数赋值
        strncpy(infoList.data[i].vendor, cpu.vendor, strlen(cpu.vendor));
        strncpy(infoList.data[i].model, cpu.model, strlen(cpu.model));
        infoList.data[i].mhz = cpu.mhz;
        infoList.data[i].mhz_max = cpu.mhz_max;
        infoList.data[i].mhz_min = cpu.mhz_min;
        infoList.data[i].cache_size = cpu.cache_size;
        infoList.data[i].total_sockets = cpu.total_sockets;
        infoList.data[i].total_cores = cpu.total_cores;
        infoList.data[i].cores_per_socket = cpu.cores_per_socket;
    }

    sigar_cpu_info_list_destroy(sigar, &cpu_infos);

    sigar_close(sigar);
}

//获取cpu的状态以及占用率
void cpu::getCpuStat(dome_cpu_stat_list &cpu_stat_list)
{
    memset(&cpu_stat_list, 0, sizeof(dome_cpu_stat_list));//置空结构体

    sigar_t *sigar;
    sigar_open(&sigar);

    //获取每个cpu的状态，系统可能有多个cpu（多核）
    sigar_cpu_list_t cpulist;
    sigar_cpu_list_get(sigar, &cpulist);

    cpu_stat_list.number = cpulist.number;
    cpu_stat_list.size = cpulist.size;
    //申请存储空间
    cpu_stat_list.data = new dome_cpu_stat[cpulist.number];

    for(unsigned long i = 0; i < cpulist.number; ++i)
    {
        memset(&cpu_stat_list.data[i], 0, sizeof(dome_cpu_stat));
        //结构体赋值
        cpu_stat_list.data[i].user = cpulist.data[i].user;
        cpu_stat_list.data[i].sys = cpulist.data[i].sys;
        cpu_stat_list.data[i].nice = cpulist.data[i].nice;
        cpu_stat_list.data[i].idle = cpulist.data[i].idle;
        cpu_stat_list.data[i].wait = cpulist.data[i].wait;
        cpu_stat_list.data[i].irq = cpulist.data[i].irq;
        cpu_stat_list.data[i].soft_irq = cpulist.data[i].soft_irq;
        cpu_stat_list.data[i].stolen = cpulist.data[i].stolen;
        cpu_stat_list.data[i].total = cpulist.data[i].total;
    }

    sigar_close(sigar);
}

void cpu::getCpuPerc(dome_cpu_perc_list &cpu_perc_list)
{
    sigar_t *sigar;
    sigar_open(&sigar);

    cout << "pid: " << sigar_pid_get(sigar) << endl;

    // 获取总的cpu使用率（不确定是不是总的，可能是第一个cpu的占用率）
    double allCombined = 0;
    sigar_cpu_t old;
    sigar_cpu_get(sigar, &old);

    //获取每个cpu的使用率
    sigar_cpu_list_t old_cpulist;
    sigar_cpu_list_get(sigar, &old_cpulist);

    sigar_cpu_t oldCpu[old_cpulist.number];
    for(unsigned long i = 0; i < old_cpulist.number; ++i)
    {
        oldCpu[i] = old_cpulist.data[i];
    }
    // 睡眠一秒，cpu使用率的计算的周期性的，需要用到cpu前后状态的数据
    Sleep(1 * 1000);

    sigar_cpu_t new1;
    sigar_cpu_get(sigar, &new1);
    sigar_cpu_perc_t cpu_prec_info;
    sigar_cpu_perc_calculate(&old, &new1, &cpu_prec_info);
    allCombined = cpu_prec_info.combined;
    cout << "cpuAll: " << allCombined * 100 << endl;

    sigar_cpu_list_t new_cpulist;
    sigar_cpu_list_get(sigar, &new_cpulist);

    sigar_cpu_t newCpu[new_cpulist.number];
    for(unsigned long i = 0; i < new_cpulist.number; ++i)
    {
        newCpu[i] = new_cpulist.data[i];
    }

    memset(&cpu_perc_list, 0, sizeof(dome_cpu_perc_list));
    cpu_perc_list.number = new_cpulist.number;
    cpu_perc_list.size = new_cpulist.size;
    cpu_perc_list.data = new dome_cpu_perc[new_cpulist.number];

    for(unsigned long i = 0; i < new_cpulist.number; ++i)
    {
        sigar_cpu_perc_t cpu_prec_info;
        //计算cpu的使用率等其他信息
        sigar_cpu_perc_calculate(&oldCpu[i], &newCpu[i], &cpu_prec_info);

        memset(&cpu_perc_list.data[i], 0, sizeof(dome_cpu_perc));
        cpu_perc_list.data[i].user = cpu_prec_info.user;
        cpu_perc_list.data[i].sys = cpu_prec_info.sys;
        cpu_perc_list.data[i].nice = cpu_prec_info.nice;
        cpu_perc_list.data[i].idle = cpu_prec_info.idle;
        cpu_perc_list.data[i].wait = cpu_prec_info.wait;
        cpu_perc_list.data[i].irq = cpu_prec_info.irq;
        cpu_perc_list.data[i].soft_irq = cpu_prec_info.soft_irq;
        cpu_perc_list.data[i].stolen = cpu_prec_info.stolen;
        cpu_perc_list.data[i].combined = cpu_prec_info.combined;

        cout << "cpu" << i << ": " << cpu_prec_info.combined * 100 << endl;


    }
}
